package com.junzhiit.nengji.shop.service.impl;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bainaeco.framework.util.DateUtil;
import com.junzhiit.nengji.bo.CouponSearchBO;
import com.junzhiit.nengji.bo.CouponsDetailsBO;
import com.junzhiit.nengji.bo.RedeemCodeBO;
import com.junzhiit.nengji.bo.UserCouponsInfoBO;
import com.junzhiit.nengji.dao.CouponsDAO;
import com.junzhiit.nengji.dao.RedeemCodeDAO;
import com.junzhiit.nengji.dao.UserCouponsDAO;
import com.junzhiit.nengji.model.Coupons;
import com.junzhiit.nengji.model.UserCoupons;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.Status;
import com.junzhiit.nengji.shop.service.CouponsService;
import com.junzhiit.nengji.shop.web.exception.CouponsAlreadyExistsException;
import com.junzhiit.nengji.shop.web.exception.CouponsExpiredException;
import com.junzhiit.nengji.shop.web.exception.CouponsInvalidException;
import com.junzhiit.nengji.shop.web.vo.CouponSearchVO;
import com.junzhiit.nengji.shop.web.vo.CouponsDetailsVO;
import com.junzhiit.nengji.shop.web.vo.ResultVO;


@Service
public class CouponsServiceImpl extends BaseServiceImpl implements CouponsService {
	
	@Autowired
	private CouponsDAO couponsDAO;
	
	@Autowired
	private UserCouponsDAO userCouponsDAO;
	
	@Autowired
	private RedeemCodeDAO redeemCodeDAO;

	@Override
	public ResultVO findAllByUser(CouponSearchVO vo,String csId,Integer isChain,int pageNumber, int maxPageRow) {
		ResultVO result = new ResultVO();
		CouponSearchBO bo = new CouponSearchBO();
		BeanUtils.copyProperties(vo, bo);
		List<UserCouponsInfoBO> list = couponsDAO.findAllByUser(bo,csId,isChain, pageNumber,  maxPageRow);
		List<CouponsDetailsVO> voList = formatCoupons(list);
		Integer cont = couponsDAO.getTotalCount(bo);
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("list",voList);
		map.put("count",cont);
		result.setData(map);
		return result;
	}
	
	public String formatDouble(double number) {
		String moneyStr = String.valueOf(number);
		String[] num = moneyStr.split("\\.");
		if (num.length == 2) {
			if(Integer.parseInt(num[1])>0){
				return new DecimalFormat("#.#").format(number);
			}else{
				return num[0];
			}
		} else {
			return num[0];
		}
	}
	
	@Override
	public ResultVO findAll(String userId,String csId,String shopId,Integer isChain,int pageNumber, int maxPageRow) {
		ResultVO result = new ResultVO();
		List<CouponsDetailsVO> voList = new ArrayList<CouponsDetailsVO>();
		List<CouponsDetailsBO> list = couponsDAO.findAll(userId,csId,shopId,isChain,pageNumber,maxPageRow);
		voList = formatCouponsByUserCouponsBO(list);
		Integer cont = couponsDAO.getTotalCount(userId);
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("list",voList);
		map.put("count",cont);
		result.setData(map);
		return result;
	}

	@Override
	public ResultVO insert(String userId, String couponsId) {
		ResultVO result = new ResultVO();
		Coupons coupons = couponsDAO.query(couponsId);
		UserCoupons userCoupons = userCouponsDAO.getUserCouponsByCouponsId(userId,couponsId);
		if(userCoupons!=null){
			userCoupons.setStatus(Status.INACTIVE.toIntStatus());
			userCouponsDAO.update(userCoupons);
		}
		userCoupons = new UserCoupons();
		BeanUtils.copyProperties(coupons, userCoupons);
		if(coupons.getValidTimeState()==0){
			userCoupons.setStartTime(coupons.getValidStartTime());
			userCoupons.setEndTime(coupons.getValidEndTime());
		}else{
			Date now=new Date();
			Date date=DateUtil.addDays(now, coupons.getValidDays());
			userCoupons.setStartTime(now);
			userCoupons.setEndTime(date);
		}
		userCoupons.setStatus(Is.NO.toIntValue());
		userCoupons.setUserId(userId);
		userCoupons.setShopId(coupons.getShopId());
		userCoupons.setCouponsName(coupons.getName());
		userCoupons.setCouponsId(couponsId);
		userCoupons.setCouponsType(coupons.getType());
		userCoupons.setChainId(coupons.getChainId());
		userCoupons.setIsChain(coupons.getIsChain());
		if(coupons.getType()==0){
			//等于1为随机劵
			if(coupons.getIsOpenRandom()==1){
				//在条件为0.6,3的10万次测试中取Max、Min的比例为0.053%，在1-100区间内大于60的占30%
				Double offer =  this.randomWeights(coupons.getStartPrice(),coupons.getEndPrice(), 0.6,2);
				userCoupons.setPrice(offer);
			}else{
				userCoupons.setPrice(coupons.getPrice());
			}
		}
		result.setData(userCouponsDAO.insert(userCoupons));
		return result;
	}
	
	/**
	 * maxProportion：代表权重衡量的区间段的大小,取值为(0.1~0.9),值越大代表权重区间值越小即越接近于Max
	 * weights：权重,取值为(1~9),值越大代表在权重区间取值的比重越大
	 * */
	private Double randomWeights(Double min,Double max,Double maxProportion,int weights){
		weights = weights>=10 && weights<0 ?1:weights;
		maxProportion = maxProportion>=1 && maxProportion<0 ?0.1:maxProportion;
		Double median = (maxProportion*(max-min))+min;
		Double result = new Double(0);
		List<Double> list = new ArrayList<Double>();
		for(int i = 1;i<=10;i++){
			if(i<=weights){
				list.add( (Math.random()*(max-median))+median);
			}else{
				list.add( (Math.random()*(median-min))+min);
			}
		}
		result = list.get((int)(1+Math.random()*(10-1)));
		return Double.parseDouble(new DecimalFormat("#.##").format(result));
	}
	
	@Override
	@Transactional
	public ResultVO exchange(String promoCode, String userId,String csId,Integer isChain) {
		ResultVO result = new ResultVO();
		//1.检测优惠劵码是否存在(是否可领取)
		RedeemCodeBO coupons = null;
		if(StringUtils.isNotBlank(csId)){
			coupons = redeemCodeDAO.checkReceive(promoCode,csId,isChain);
			if(coupons == null){
				//优惠码无效
				throw new CouponsInvalidException("优惠码无效,该商家没有此优惠码");
			}
		}else{
			coupons = redeemCodeDAO.checkEffective(promoCode);
			if(coupons == null){
				//优惠码无效
				throw new CouponsInvalidException("优惠码无效");
			}
		}
		
		if(coupons.getIsDelete() == Is.YES.toIntValue()){
			//优惠码过期
			throw new CouponsExpiredException("优惠码失效");
		}
		if( coupons.getRedeemCodeDelete() == Is.YES.toIntValue()){
			//优惠码已经被领取
			throw new CouponsAlreadyExistsException("该优惠劵已经被领取过");
		}
		
		//2.检查用户是否已经领取过优惠劵
		UserCoupons userCoupons = userCouponsDAO.getUserCouponsByCouponsId(userId,coupons.getId());
		if(userCoupons!=null){
			//已经领取过该优惠劵
			throw new CouponsAlreadyExistsException("已经领取过该优惠劵");
		}
		
		//3.修改该优惠劵码状态
		redeemCodeDAO.isDelete(promoCode);
		//4.用户领取优惠劵
		userCoupons = new UserCoupons();
		BeanUtils.copyProperties(coupons, userCoupons);
		if(coupons.getValidTimeState()==0){
			userCoupons.setStartTime(coupons.getValidStartTime());
			userCoupons.setEndTime(coupons.getValidEndTime());
		}else{
			Date now=new Date();
			Date date=DateUtil.addDays(now, coupons.getValidDays());
			userCoupons.setStartTime(now);
			userCoupons.setEndTime(date);
		}
		userCoupons.setStatus(Is.NO.toIntValue());
		userCoupons.setUserId(userId);
		userCoupons.setShopId(coupons.getShopId());
		userCoupons.setCouponsName(coupons.getName());
		userCoupons.setCouponsId(coupons.getId());
		userCoupons.setCouponsType(coupons.getType());
		userCoupons.setChainId(coupons.getChainId());
		userCoupons.setIsChain(coupons.getIsChain());
		if(coupons.getType()==0){
			//等于1为随机劵
			if(coupons.getIsOpenRandom()==1){
				//在条件为0.6,3的10万次测试中取Max、Min的比例为0.053%，在1-100区间内大于60的占30%
				Double offer =  this.randomWeights(coupons.getStartPrice(),coupons.getEndPrice(), 0.6,2);
				userCoupons.setPrice(offer);
			}else{
				userCoupons.setPrice(coupons.getPrice());
			}
		}
		result.setData(userCouponsDAO.insert(userCoupons));
		return result;
	}
	
	public List<CouponsDetailsVO> formatCoupons(List<UserCouponsInfoBO> list){
		List<CouponsDetailsVO> voList = new ArrayList<CouponsDetailsVO>();
		for(int i =0;i<list.size();i++){
			UserCouponsInfoBO cdBo = list.get(i);
			CouponsDetailsVO cdVo = new CouponsDetailsVO();
			cdVo.setCouponsType(cdBo.getCouponsType());
			cdVo.setIsOpenRandom(cdBo.getIsOpenRandom());
			cdVo.setPlatform(cdBo.getPlatform());
			if(cdBo.getPlatform() == 0){
				if(cdBo.getIsChain() == Is.YES.toIntValue()){
					cdVo.setOwnName("品牌劵");
				}else{
					cdVo.setOwnName(cdBo.getShopName());
				}
			}else if(cdBo.getPlatform() == 2){
				cdVo.setOwnName("平台劵");
			}
			//等于0为指定金额
			if(cdBo.getCouponsType()==0){
				//是否为随机劵为1则是随机劵
				cdVo.setCouponsName("现金劵");
				cdVo.setFaceValue(this.formatDouble(cdBo.getPrice()));
			}else{
				//等于1为折扣
				cdVo.setCouponsName("折扣劵");
				cdVo.setFaceValue(this.formatDouble(cdBo.getDiscount()));
			}
			//等于0为无门槛
			cdVo.setThreshold(cdBo.getThreshold());
			if(cdBo.getThreshold()==0){
				cdVo.setRemarks("无门槛");
			}else{
				//等于1为有门槛
				cdVo.setFullPriceReduction(cdBo.getFullPriceReduction());
				cdVo.setRemarks("满"+this.formatDouble(cdBo.getFullPriceReduction())+"元可用");
			}
			cdVo.setId(cdBo.getId());
			if(cdBo.getValidDays()!=null && cdBo.getValidDays()>0){
				Date date=DateUtil.addDays(cdBo.getStartTime(), cdBo.getValidDays());
				cdVo.setValidEndTime(date);
			}else{
				cdVo.setValidEndTime(cdBo.getEndTime());
			}
			cdVo.setShopId(cdBo.getShopId());
			cdVo.setChainId(cdBo.getChainId());
			cdVo.setIsChain(cdBo.getIsChain());
			voList.add(cdVo);
		}
		return voList;
	}
	
	public List<CouponsDetailsVO> formatCouponsByUserCouponsBO(List<CouponsDetailsBO> list){
		List<CouponsDetailsVO> voList = new ArrayList<CouponsDetailsVO>();
		for(int i =0;i<list.size();i++){
			CouponsDetailsBO cdBo = list.get(i);
			CouponsDetailsVO cdVo = new CouponsDetailsVO();
			cdVo.setCouponsType(cdBo.getType());
			cdVo.setIsOpenRandom(cdBo.getIsOpenRandom());
			cdVo.setPlatform(cdBo.getPlatform());
			if(cdBo.getPlatform()!=null){
				if(cdBo.getPlatform() == 0){
					if(cdBo.getIsChain() == Is.YES.toIntValue()){
						cdVo.setOwnName("品牌劵");
					}else{
						cdVo.setOwnName(cdBo.getShopName());
					}
				}else if(cdBo.getPlatform() == 2){
					cdVo.setOwnName("平台劵");
				}
			}
			//等于0为指定金额
			if(cdBo.getType()==0){
				//是否为随机劵为1则是随机劵
				cdVo.setCouponsName("现金劵");
				if(cdBo.getIsOpenRandom()==1){
					cdVo.setFaceValue(this.formatDouble(cdBo.getStartPrice())+"~"+this.formatDouble(cdBo.getEndPrice()));
				}else{
					cdVo.setFaceValue(this.formatDouble(cdBo.getPrice()));
				}
			}else{
				//等于1为折扣
				cdVo.setCouponsName("折扣劵");
				cdVo.setFaceValue(this.formatDouble(cdBo.getDiscount()));
			}
			//等于0为无门槛
			cdVo.setThreshold(cdBo.getThreshold());
			if(cdBo.getThreshold()==0){
				cdVo.setRemarks("无门槛");
			}else{
				//等于1为有门槛
				cdVo.setFullPriceReduction(cdBo.getFullPriceReduction());
				cdVo.setRemarks("满"+this.formatDouble(cdBo.getFullPriceReduction())+"元可用");
			}
			cdVo.setId(cdBo.getId());
			if(cdBo.getValidDays()!=null && cdBo.getValidDays()>0){
				Date date = null;
				if(cdBo.getValidStartTime() == null){
					date=DateUtil.addDays(new Date(), cdBo.getValidDays());
				}else{
					date=DateUtil.addDays(cdBo.getValidStartTime(), cdBo.getValidDays());
				}
				cdVo.setValidEndTime(date);
			}else{
				cdVo.setValidEndTime(cdBo.getValidEndTime());
			}
			cdVo.setShopId(cdBo.getShopId());
			cdVo.setChainId(cdBo.getChainId());
			cdVo.setIsChain(cdBo.getIsChain());
			voList.add(cdVo);
		}
		return voList;
	}
}
